import java.util.*;
import java.util.stream.*;

public class Test {
    public static void main(String[] args) {
        List<String> raw = List.of("tom", "jerry", "alice", "bob", "tom");

        /* ---------- 1. 转换操作 ---------- */
        // 1.1 map: 字符串 → 长度
        List<Integer> lengths = raw.stream()
                .map(String::length)
                .collect(Collectors.toList());
        System.out.println("map (长度)     : " + lengths);

        // 1.2 filter: 只保留长度 > 3 的名字
        List<String> filtered = raw.stream()
                .filter(s -> s.length() > 3)
                .collect(Collectors.toList());
        System.out.println("filter (>3)   : " + filtered);

        // 1.3 sorted: 按字母排序
        List<String> sorted = raw.stream()
                .sorted()
                .collect(Collectors.toList());
        System.out.println("sorted        : " + sorted);

        // 1.4 distinct: 去重
        List<String> distinct = raw.stream()
                .distinct()
                .collect(Collectors.toList());
        System.out.println("distinct      : " + distinct);

        /* ---------- 2. 合并操作 ---------- */
        List<Integer> nums1 = List.of(1, 2, 3);
        List<Integer> nums2 = List.of(4, 5, 6);

        // 2.1 concat: 把两个流首尾相接
        List<Integer> concat = Stream.concat(nums1.stream(), nums2.stream())
                .collect(Collectors.toList());
        System.out.println("concat        : " + concat);

        // 2.2 flatMap: 把嵌套集合摊平
        List<List<Integer>> nested = List.of(
                List.of(1, 2),
                List.of(3, 4),
                List.of(5));
        List<Integer> flat = nested.stream()
                .flatMap(List::stream)
                .collect(Collectors.toList());
        System.out.println("flatMap       : " + flat);

        /* ---------- 3. 并行处理 ---------- */
        // parallel: 把流标记为并行（底层 ForkJoinPool）
        List<Integer> parallel = IntStream.range(0, 10)
                .parallel()
                .boxed()
                .collect(Collectors.toList());
        System.out.println("parallel      : " + parallel);

        /* ---------- 4. 聚合操作 ---------- */
        List<Integer> nums = List.of(1, 2, 3, 4, 5, 6, 7, 8, 9);

        // 4.1 reduce: 累加
        int sum = nums.stream()
                .reduce(0, Integer::sum);
        System.out.println("reduce (sum)  : " + sum);

        // 4.2 collect: 收集成 List
        List<Integer> collected = nums.stream()
                .collect(Collectors.toList());
        System.out.println("collect       : " + collected);

        // 4.3 count: 元素个数
        long count = nums.stream().count();
        System.out.println("count         : " + count);

        // 4.4 max / min: 最大 / 最小
        Optional<Integer> max = nums.stream().max(Integer::compareTo);
        Optional<Integer> min = nums.stream().min(Integer::compareTo);
        System.out.println("max           : " + max.orElse(null));
        System.out.println("min           : " + min.orElse(null));

        // 4.5 sum / average (IntStream 专用)
        IntStream intStream = nums.stream().mapToInt(Integer::intValue);
        System.out.println("sum           : " + intStream.sum());
        System.out.println("average       : " + nums.stream().mapToInt(Integer::intValue).average().orElse(0));

        /* ---------- 5. 匹配操作 ---------- */
        // 5.1 allMatch: 全部满足
        boolean allEven = nums.stream().allMatch(n -> n % 2 == 0);
        System.out.println("allMatch 偶数 ?: " + allEven);

        // 5.2 anyMatch: 任意满足
        boolean hasEven = nums.stream().anyMatch(n -> n % 2 == 0);
        System.out.println("anyMatch 偶数 ?: " + hasEven);

        /* ---------- 6. 遍历操作 ---------- */
        // forEach: 消费每个元素（顺序由流决定）
        System.out.print("forEach       : ");
        nums.stream().forEach(n -> System.out.print(n + " "));
        System.out.println();
    }
}